package cn.xxliang.aiproject.trigger.http;

import cn.xxliang.aiproject.api.IRAGService;
import cn.xxliang.aiproject.api.response.Response;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
import org.redisson.Redisson;
import org.redisson.api.RList;
import org.redisson.api.RedissonClient;
import org.springframework.ai.document.Document;
import org.springframework.ai.ollama.OllamaChatClient;
import org.springframework.ai.reader.tika.TikaDocumentReader;
import org.springframework.ai.transformer.splitter.TokenTextSplitter;
import org.springframework.ai.vectorstore.PgVectorStore;
import org.springframework.ai.vectorstore.SimpleVectorStore;
import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.PathResource;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.List;

/**
 * @author xxliang
 * @date 2025/7/5  18:05
 * @description 上传知识库的相关的接口
 */
@Slf4j
@RestController
@CrossOrigin("*")
@RequestMapping("/api/v1/rag")
public class RAGController implements IRAGService {
    @Resource
    private OllamaChatClient ollamaChatClient;

    @Resource
    private TokenTextSplitter tokenTextSplitter;

    @Resource
    private SimpleVectorStore simpleVectorStore;

    @Resource
    private PgVectorStore pgVectorStore;

    @Resource
    private RedissonClient redissonClient;

    //获取知识库列表；
    @Override
    @GetMapping(value = "/query/getRagList")
    public Response<List<String>> queryRagTagList() {

        RList<String> redisRagList = redissonClient.getList("ragTag");
        if (redisRagList == null || redisRagList.size() == 0) {
            return Response.success(null);
        }
        List<String> ragList = redisRagList.readAll();
        return Response.success(ragList);
    }
    //http://localhost:8090/api/v1/rag/file/upload
    @Override
    @PostMapping(value = "/file/upload")
    public Response<String> uploadRag(@RequestParam String ragTag, @RequestParam MultipartFile file) {
        log.info("上传知识库开始 {}",ragTag);

            //加载文件
            TikaDocumentReader reader = new TikaDocumentReader(file.getResource());
            //这行代码调用 TikaDocumentReader 的 get() 方法，加载并解析上传的文件内容，返回一个包含文档内容的 List<Document> 集合。
            List<Document> documents = reader.get();
            //使用 tokenTextSplitter 对加载的文档内容进行分割处理，将大文本按指定规则切分为多个较小的文档片段。
            List<Document> apply = tokenTextSplitter.apply(documents);
            //为每个片段打Tag
            documents.forEach(doc->doc.getMetadata().put("ragTag",ragTag));
            apply.forEach(doc->doc.getMetadata().put("ragTag",ragTag));

            //上传到向量数据库
            pgVectorStore.accept(apply);
            //检查Redis中的List是否拥有ragTag'元素；
            RList<String> redisRagList = redissonClient.getList("ragTag");
            if (!redisRagList.contains(ragTag)){
                //上传到redis
                redisRagList.add(ragTag);
            }else{
                return Response.error("上传失败，已经上传该知识库~");
            }


        return Response.success("上传成功！");
    }

    @PostMapping(value = "/git/upload")
    @Override
    public Response<String> uploadRagFromGit(String ragTag, String repoUrl, String username, String password) {
        String localPath = "D:\\JGit";
        //清空本地仓库
        try {
            FileUtils.deleteDirectory(new File(localPath));
        } catch (IOException e) {
            log.info("删除成功");
        }

        //克隆仓库
        Git call = null;
        try {
            call = Git.cloneRepository()
                    //设置仓库地址
                    .setURI(repoUrl)
                    //设置克隆地址
                    .setDirectory(new File(localPath))
                    //设置用户名和密码
                    .setCredentialsProvider(new UsernamePasswordCredentialsProvider(username, password)).call();
        } catch (GitAPIException e) {
            log.info("项目克隆失败；请重试或联系管理员");
        }

        //遍历这套库存
        try {
            test_file("");
        } catch (Exception e) {
            log.info("文件上传知识库失败..,请重试或联系管理员");
        }

        call.close();//先关闭链接

        return Response.success("上传成功..");
    }
    public  void test_file(String localPath) throws Exception {
        Path path = Files.walkFileTree(Paths.get(localPath), new SimpleFileVisitor<>(){
            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                log.info("文件路径：{}",file.toString());
                //创建一个 Resource 对象
                PathResource pathResource = new PathResource(file);
                log.info("开始上传知识库");
                TikaDocumentReader reader = new TikaDocumentReader(pathResource);
                List<Document> documents = reader.get();
                List<Document> apply = tokenTextSplitter.apply(documents);
                documents.forEach(doc -> doc.getMetadata().put("knowledge", "xxliang-yunc"));
                apply.forEach(doc -> doc.getMetadata().put("knowledge", "xxliang-yunc"));

                pgVectorStore.accept( apply);
                log.info("上传完成");
                return FileVisitResult.CONTINUE;
            }
        });
    }

}

